<?php

abstract class Query
{
    abstract protected function record(array $data);

    protected function select()
    {
        $this->record(['name' => '张三', 'age' => 18, 'mobile' => '12345678900']);
    }
}

class UserModel extends Query
{
    public array $field = [];

    protected function record(array $data)
    {
        $this->field = $data;
    }

    public function all(): array
    {
        $this->select();
        return $this->field;
    }

    // private function mobile()
    // {
    //     return '123123123';
    // }

    public function __get($name)
    {
        if (method_exists($this, $name)) {
            return call_user_func_array([$this, $name], []);
            // $this->$name();
        } else {
            throw new Exception('参数错误');
        }
        // if (!isset($this->field[$name])) {
        //     return $this->$name();
        // } else {
        //     throw new Exception('参数错误');
        // }
    }

    public function __set($name, $value): void
    {
        if (!isset($this->field[$name])) {
            $this->field[$name] = $value;
        } else {
            throw new Exception('参数错误');
        }
    }

    public function __unset(string $name): void
    {
        if (isset($this->field[$name])) {
            $this->field[$name] = '';
        } else {
            throw new Exception('参数不存在');
        }
    }

    // 判断属性是否存在
    public function __isset(string $name): bool
    {
        return isset($this->field[$name]);
    }

    public function __call(string $name, array $arguments)
    {
        $action = 'getAttribute'.$name;
        if (method_exists($this, $action)) {
            return call_user_func_array([$this, $action], $arguments);
        } else {
            return null;
        }
    }

    public static function __callStatic(string $name, array $arguments)
    {
        switch ($name) {
            case 'getAll':
                return call_user_func_array([new static(), 'all'], $arguments);
            default:
                $obj = new static();
                $obj->all();
                return call_user_func([$obj, '__call'], $name, $arguments);
        }
    }
}

class User extends UserModel
{
    protected function getAttributeMobile($len = 9)
    {
        return substr($this->field['mobile'], 0, $len).'***';
    }
}

// __get() __set()对属性进行检测
try {
    // $user = new UserModel();
    // echo $user->mobile;
    // $user->address = '云南昆明';
    // var_dump($user->field);
    // var_dump($user->all());
    // unset($user->name);
    // var_dump($user->field);
    // var_dump(isset($user->abc));
    // $user = new User;
    // $user->all();
    // var_dump($user->mobile()); // 调用一个不存在的方法
    var_dump(User::getAll());
    var_dump(User::mobile());
} catch (Exception $e) {
    echo $e->getMessage();
}
